package soccerscope.view;

import java.awt.event.ActionEvent;
import java.util.List;
import java.util.Vector;

import javax.swing.JComboBox;

import soccerscope.model.PlayMode;
import soccerscope.model.ScenePlayModeList;
import soccerscope.model.ScenePlayModeListItem;
import soccerscope.model.ScenePlayModeListObserver;
import soccerscope.model.SceneSet;
import soccerscope.model.WorldModel;

/**
 * Implements a GUI element to jump to scenes where the play mode has changed.
 * The SCenes are combined by play modes.
 * 
 * @author benjaboe
 * 
 */
public class PlayModeSortedJumper
    extends AbstractSceneJumper
    implements ScenePlayModeListObserver {

  private static final long serialVersionUID = -5531019185760203025L;

  /** Box where the available play modes could be choosed. */
  private JComboBox         modes;

  /** Box where the scenes for the mode choosen in modes could be choosed. */
  private JComboBox         scenesOfModes;

  /** Saves all play modes, which are shown in the box modes. */
  private List<PlayMode>    modesInBox;

  private ScenePlayer       scenePlayer;

  /**
   * Creates the GUI element.
   * 
   * @param scenePlayer
   *          the ScenePlayer to jumpt to a choosen scene
   */
  public PlayModeSortedJumper(
      ScenePlayer scenePlayer) {

    super(scenePlayer);
    this.scenePlayer = scenePlayer;
    SceneSet sceneSet = WorldModel.getSceneSet();
    ScenePlayModeList pml = sceneSet.getScenePlayModeList();

    this.modesInBox = pml.getOccuredModes();
    this.modes = new JComboBox(new Vector(this.modesInBox));
    this.add(this.modes);
    this.modes.addActionListener(this);
    pml.addObserver(this);
    this.chooseMode();
  }

  /**
   * Builds a ComboBox with the Scenes of the play mode, which is selected in
   * the box modes.
   */
  private void chooseMode() {

    if (this.scenesOfModes != null) {
      this.remove(this.scenesOfModes);
    }

    SceneSet sceneSet = WorldModel.getSceneSet();
    ScenePlayModeList pml = sceneSet.getScenePlayModeList();

    PlayMode selectedMode = (PlayMode) this.modes.getSelectedItem();
    this.scenesOfModes = new JComboBox(new Vector(pml
        .getScenesByPlayMode(selectedMode)));
    this.add(this.scenesOfModes);
    if (this.getParent() != null) {
      this.scenesOfModes.setVisible(true);
      this.getParent().invalidate();
      this.invalidate();
      this.scenesOfModes.invalidate();
      this.getParent().doLayout();
      this.doLayout();
      this.scenesOfModes.doLayout();
    }
  }

  /**
   * This method is called, when a the play mode has changed
   * 
   * @param item
   *          the scene number and the new play mode in one object
   */
  public void newScenePlayModeAdded(ScenePlayModeListItem item) {

    if (!this.modesInBox.contains(item.getMode())) {
      this.modesInBox.add(item.getMode());
      this.modes.addItem(item.getMode());
    }
    else if (this.modes.getSelectedItem().equals(item.getMode())) {
      this.scenesOfModes.addItem(item);
    }
  }

  /**
   * Thie method is called, when the whole list has changed, e.g. after loading
   * 
   */
  public void allChanged() {

    SceneSet sceneSet = WorldModel.getSceneSet();
    ScenePlayModeList pml = sceneSet.getScenePlayModeList();

    this.remove(this.modes);
    this.modesInBox = pml.getOccuredModes();
    this.modes = new JComboBox(new Vector(this.modesInBox));
    this.add(this.modes);
    this.modes.addActionListener(this);
    this.modes.setVisible(true);
    this.chooseMode();
  }

  /**
   * will be called when the selection in the box modes has changed or if the
   * jump button has be clicked.
   */
  public void actionPerformed(ActionEvent e) {

    if (e.getSource() == this.modes) {
      this.chooseMode();
    }
    else {
      this.jumpToScene(((ScenePlayModeListItem) this.scenesOfModes
          .getSelectedItem()).getScene());
    }
    this.scenePlayer.repaint();
  }

}
